﻿using System;
using System.IO;
using System.Windows.Media.Imaging;
using System.Drawing;
using System.Windows.Interop;
using System.Windows;
using CalcSharp.Core.Containers;
using System.Drawing.Imaging;

namespace CalcSharp.Core
{
    public class HDPhotoDriver
    {
        private Stream Src;

        public HDPhotoDriver(Stream imgStream)
        {
            this.Src = imgStream;
        }

        private BitmapSource convertBitmapToBitmapSource(Bitmap bmp)
        {
            BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            return bitmapSource;
        }

        private Bitmap GetBitmap(BitmapSource bms)
        {
            int width = bms.PixelWidth;
            int height = bms.PixelHeight;
            int stride = width * ((bms.Format.BitsPerPixel + 7) / 8);

            byte[] bits = new byte[height * stride];

            bms.CopyPixels(bits, stride, 0);

            unsafe
            {
                fixed (byte* pBits = bits)
                {
                    IntPtr ptr = new IntPtr(pBits);

                    System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(
                        width,
                        height,
                        stride,
                        PixelFormat.Format32bppPArgb,
                        ptr);

                    return bitmap;
                }
            }
        }


        public Bitmap ReadBitmap()
        {
            WmpBitmapDecoder dec = new WmpBitmapDecoder(Src, BitmapCreateOptions.None, BitmapCacheOption.Default);
            return this.GetBitmap((BitmapSource)dec.Frames[0]);
        }

        public void WriteBitmap(Bitmap bmp, int quality)
        {
            WmpBitmapEncoder wbeFile = new WmpBitmapEncoder();
            BitmapSource bs = Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            if (quality < 1) quality = 1;
            if (quality > 100) quality = 100;
            wbeFile.ImageQualityLevel = (float)quality / 100;
            wbeFile.Frames.Add(BitmapFrame.Create(bs));
            wbeFile.Save(Src);
            Src.Close();
        }

        public AMatrix ReadMatrix(out long mem, MtrxStorageType t)
        {
            AMatrix ret;
            WmpBitmapDecoder dec = new WmpBitmapDecoder(Src, BitmapCreateOptions.None, BitmapCacheOption.Default);
            Bitmap bmp = this.GetBitmap((BitmapSource)dec.Frames[0]);
            Int24 cnv = new Int24();
            switch (t)
            {
                case MtrxStorageType.tdouble:
                    ret = new DoubleMatrix((int)bmp.Height, (int)bmp.Width);
                    break;
                case MtrxStorageType.tfloat:
                    ret = new FloatMatrix((int)bmp.Height, (int)bmp.Width);
                    break;
                case MtrxStorageType.tint24:
                    ret = new Int24Matrix((int)bmp.Height, (int)bmp.Width);
                    break;
                default:
                    ret = new FloatMatrix((int)bmp.Height, (int)bmp.Width);
                    break;
            }
            mem = bmp.Height * bmp.Width * (int)t;

            for (int i = 0; i < bmp.Height; i++)
            {
                for (int j = 0; j < bmp.Width; j++)
                {
                    cnv.FromColor(bmp.GetPixel(j, i));
                    ret[i, j] = cnv.ToInt32();
                }
            }
            return ret;
        }

    }
}
